/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bankingsystem;

import java.io.Serializable;
import java.text.DecimalFormat;
import java.util.Date;

/**
 * This is the class for a Loan object.
 * It contains methods to make payments, update the loan, view the interest rate
 * and also to view the details of the loan.
 * @author Sumedha
 */
public class Loan implements Serializable{

    /**
     * Variable to keep data regarding the loan
     */
    private int loanNo;
    private double amount;
    private Customer customer;
    private double interestRate;
    private Date startingDate;
    private Date endingDate;
    private int durationInMonths;

    /**
     * Creates a new loan Object
     * @param loanNo    Number of the loan
     * @param amount    Initial amount
     * @param customer  Customer who is responsible for the loan
     * @param interestRate  Initial interest rate
     * @param startingDate  Starting date of the loan
     */
    public Loan(int loanNo, double amount, Customer customer,
            double interestRate, Date startingDate, int duration) {
        this.loanNo = loanNo;
        this.amount = amount;
        this.customer = customer;
        this.interestRate = interestRate;
        this.startingDate = startingDate;
        this.durationInMonths = duration;
        setEndingDate(duration);

    }

    /**
     * This method is responsible for making payments.That is if the customer
     * makes a payment the amount paid will be reduced from the total amount
     * of the loan. So the new loan amount will be the amount after reducing
     * the amount paid. This will happen only if the duration of the loan is not
     * exceeded.
     * Else the payments will no be made.
     *
     * @return Returns true if the loan is not paid fully. If this is the
     * last payment it will return false
     *
     * @param payment  amount to be reduced from the total loan amount
     */
    public boolean makePayment(double payment) {
        //Gets the current date(Today)
        Date currentDate = new Date();

        /**
         * Compares current date with the ending date of the loan. If the current date 
         * is before end date the validity will be less than 0
         * Refer Date.compareTo method for more details.
         */
        int validity = currentDate.compareTo(endingDate);
        if (validity < 0) {     //If the current date is before end date
            double newAmount = (getAmount() - payment);
            setAmount(newAmount);     //Sets the new amount after deducting the payment
            return true;    //Return true if the action was sucessfull
        } else {
            return false;   //Return false if the loan has expired
        }
    }

    /**
     * This method returns the value of the interest rate of the given account
     * @return Returns the interest value of the given account
     */
    public double checkInterest() {
        return getInterestRate();   //Returns the interest rate
    }

    /**
     * This method Updates the account. It calculates the new amount of the
     * loan according to the interest rate.
     * @return whether the action is completed or not
     */
    public boolean update() {

        double oldAmount = getAmount(); //previous amount of the loan
        double addition = oldAmount * (interestRate / 100); //amount to be added according to the interest rate
        double newAmount = oldAmount + addition; //new amount of the laon
        setAmount(newAmount);   //sets the loan amount to new value
        if (oldAmount < newAmount) {    //If the action is sucessfull new amount should be greater than old amount
            return true;
        } else {
            return false;
        }
    }

    /**
     * This method shows details regarding the loan. It displays all the
     * attributes of the loan object
     */
    public void showLoanDetails() {
        System.out.println("Loan No: " + getLoanNo());  //Display loan no:
        System.out.println("Customer Name: " + getCustomer().getName()); //Display Customer name
        DecimalFormat df = new DecimalFormat("Rs: #0.00"); //Formats the amount to two decimal places
        System.out.println("Amount: " + df.format(getAmount()));   //Display loan amount
        System.out.println("Iterest Rate: " + getInterestRate());   // Display interest rate
        System.out.println("Starting Date: " + getStartingDate().getDate() //Display Starting date of the loan
                + "/" + (getStartingDate().getMonth() + 1) + "/" + (getStartingDate().getYear() + 1900));
        System.out.println("Ending Date: " + getEndingDate().getDate() //Display Ending date of the loan
                + "/" + (getEndingDate().getMonth() + 1) + "/" + (getEndingDate().getYear() + 1900));

    }

    /**
     * This method sets the ending date of the loan according to the duration
     * of the loan. That is using he starting date it calculates the date
     * which should be the ending date of the loan.
     *
     * @param endingDate the endingDate to set
     */
    public final void setEndingDate(int duration) {
        //If the duration is less than 12 months it only alters the month value
        if (duration < 12) {
            this.endingDate = new Date(startingDate.getYear(),
                    startingDate.getMonth() + duration, startingDate.getDate());
        } //Else it calculates the end date according to the duraton
        else {
            int years = duration / 12;  // Calculates the years to be added
            int months = duration - years * 12; //Calculates the months to be added
            this.endingDate = new Date(startingDate.getYear() + years,
                    startingDate.getMonth() + months, startingDate.getDate());
        }
    }
/**
 * This method gives the remaining duration of a loan i months.
 * @return the remaining duration
 */
    public int getRemainingDuration() {
        Date currentDate = new Date();  //Current Date
        int months = endingDate.getMonth() - currentDate.getMonth();    //Remaining Months
        int years = endingDate.getYear() - currentDate.getYear();   // emaining years
        return months + years * 12;     //total months remaining
    }

    /**
     * @return the loanNo
     */
    public int getLoanNo() {
        return loanNo;
    }

    /**
     * @param loanNo the loanNo to set
     */
    public void setLoanNo(int loanNo) {
        this.loanNo = loanNo;
    }

    /**
     * @return the amount
     */
    public double getAmount() {
        return amount;
    }

    /**
     * @param amount the amount to set
     */
    public void setAmount(double amount) {
        this.amount = amount;
    }

    /**
     * @return the customer
     */
    public Customer getCustomer() {
        return customer;
    }

    /**
     * @param customer the customer to set
     */
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    /**
     * @return the interestRate
     */
    public double getInterestRate() {
        return interestRate;
    }

    /**
     * @return the startingDate
     */
    public Date getStartingDate() {
        return startingDate;
    }

    /**
     * @param startingDate the startingDate to set
     */
    public void setStartingDate(Date startingDate) {
        this.startingDate = startingDate;
    }

    /**
     * @return the endingDate
     */
    public Date getEndingDate() {
        return endingDate;
    }

    /**
     * @return the durationInMonths
     */
    public int getDurationInMonths() {
        return durationInMonths;
    }
}
